package genetic.q3;

import java.util.Arrays;
import java.util.List;
import java.util.Vector;

import genetic.Genotype;
import genetic.Phenotype;

public class CliquePhenotypeQ3 extends Phenotype {

	private int _size;
	private ReadFile _rf;
	public CliquePhenotypeQ3(){

	}

	public CliquePhenotypeQ3(int size, ReadFile rf){
		_size = size;
		_rf = rf;
	}

	@Override
	public Genotype createRandomInstance() {
		boolean[] instance = new boolean[_size];

		return new CliqueGenotype(instance);
	}

	@Override
	public Genotype[] crossover(Genotype g1, Genotype g2) {
		boolean[][] offsprings = singlePointCrossOver(g1.getBitString(), g2.getBitString());
		return new CliqueGenotype[]{new CliqueGenotype(offsprings[0]), new CliqueGenotype(offsprings[1])};
	}

	@Override
	public double fitness(Genotype g) {
		CliqueGenotype cg = (CliqueGenotype)g;

		int counter = 0;

		//count number of nodes
		for(int i = 0; i <_size; i++){
			if(cg.instance[i]){
				counter++;
			}
		}

		if(!isClique(g.getBitString()))
			counter=0;
		return counter;
	}

	private boolean isClique(boolean[] bitString){
		int wrong=0;
		Vector<Integer> nodes = new Vector<Integer>();
		//count number of nodes
		for(int i = 0; i <_size; i++){
			if(bitString[i]){
				nodes.add(i);
			}
		}

		for(int i = 0; i <nodes.size(); i++){
			//count number of missing arcs
			for(int j = i+1; j <nodes.size(); j++){
				if(!_rf.matrix[nodes.get(i)][nodes.get(j)]){
					wrong++;
				}
			}
		}
		return wrong==0;
	}

	@Override
	public Genotype mutate(Genotype g, double Pm) {
		boolean[] rep = Arrays.copyOf(g.getBitString(), g.getBitString().length);
		if (Math.random()<Pm){
			int loc = (int)(Math.random()*rep.length);
			rep[loc] = !rep[loc];
			if (!isClique(rep)) rep[loc] = !rep[loc];
		}
		return new CliqueGenotype(rep);
	}

	@Override
	public List<Genotype> getMatingPool(List<Genotype> population, int populationSize) {
		return population;
//		return getMatingPoolRouletteWheel(population, populationSize);
	}

}
